#pragma once
#include <iostream>
#include <string>

#include <cstring>

namespace dsh_protocol
{
    #define MYSELF 1
    #define SPACE " "
    #define SPACE_LEN strlen(SPACE)

    class Request
    {
    public:
        std::string Serialize() // 序列化 -> "x_ op_ y_"
        {
            // 自己实现
            // 现成的方案
        #ifdef MYSELF
            std::string str;
            str = std::to_string(x_);
            str += SPACE;
            str += op_;
            str += SPACE;
            str += std::to_string(y_);
            return str;
        #else
        #endif 
        }

        bool Deserialize(const std::string& str) // 反序列化 "x_ op_ y_" -> 结构化数据
        {
        #ifdef MYSELF
            std::size_t left = str.find(SPACE);
            if (left == std::string::npos) return false;
            std::size_t right = str.rfind(SPACE);
            x_ = stoi(str.substr(0, left));
            y_ = stoi(str.substr(right + SPACE_LEN));
            op_ = str[left + SPACE_LEN];
            return true;
        #else
        #endif 
        }

    public:
        Request(){}
        Request(int x, int y, char op)
            :x_(x)
            ,y_(y)
            ,op_(op)
        {}
        ~Request(){}
    public:
        int x_;
        int y_;
        char op_;
    };

    class Response
    {
    public:
        std::string Serialize() // 序列化 -> "code_ result_"
        {
        #ifdef MYSELF
            std::string s;
            s = std::to_string(code_);
            s += SPACE;
            s += std::to_string(result_);
            return s;
        #else
        #endif  
        }

        bool Deserialize(const std::string& str) // 反序列化 "code_ result_" -> 结构化数据
        {
        #ifdef MYSELF
            std::size_t pos = str.find(SPACE);
            if (pos == std::string::npos) return false;
            code_ = stoi(str.substr(0, pos));
            result_ = stoi(str.substr(pos + SPACE_LEN));
            return true;
        #else
        #endif  
        }
    public:
        Response(){}
        Response(int result, int code)
            :result_(result)
            ,code_(code)
        {}
        ~Response(){}
    public:
        int result_; // 结果
        int code_;   // 结果状态码
    };

    std::string Recv(int sock)
    {
        char inbuffer[1024];
        ssize_t s = recv(sock, inbuffer, sizeof(inbuffer), 0);
        if (s > 0)
        {
            inbuffer[s] = 0;
            return inbuffer;
        }
    }
    void Send(int sock, const std::string str)
    {
        send(sock, str.c_str(), str.size(), 0);
    }
}